<template>
  <div class="line-chart-container" :style="{ width: width + 'px', height: height + 'px' }" ref="chartRef"></div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import * as echarts from 'echarts'

interface Props {
  width?: number
  height?: number
  title?: string
  categories: string[]
  series: Array<{
    name: string
    data: number[]
    color?: string
    smooth?: boolean
  }>
  showValue?: boolean
  valueFormat?: 'number' | 'percent' | 'currency'
  precision?: number
  colors?: string[]
}

const props = withDefaults(defineProps<Props>(), {
  width: 400,
  height: 300,
  showValue: false,
  valueFormat: 'number',
  precision: 2,
  colors: () => ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399']
})

const chartRef = ref<HTMLDivElement | null>(null)
let chart: echarts.ECharts | null = null

function formatValue(value: number): string {
  switch (props.valueFormat) {
    case 'percent':
      return (value * 100).toFixed(props.precision) + '%'
    case 'currency':
      return '¥' + value.toFixed(props.precision)
    default:
      return value.toFixed(props.precision)
  }
}

function getOption() {
  return {
    title: props.title ? { text: props.title, left: 'center', top: 10 } : undefined,
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'cross' },
      formatter: (params: any) => {
        let html = ''
        if (params[0]) {
          html += `<div style='font-weight:600;margin-bottom:4px;'>${params[0].axisValue}</div>`
        }
        params.forEach((item: any) => {
          html += `
            <div>
              <span style="display:inline-block;width:10px;height:10px;background:${item.color};margin-right:6px;border-radius:2px;"></span>
              ${item.seriesName}：${formatValue(item.data)}
            </div>
          `
        })
        return html
      }
    },
    legend: { show: props.series.length > 1, top: 30 },
    grid: { left: 40, right: 20, top: 60, bottom: 40 },
    xAxis: {
      type: 'category',
      data: props.categories,
      axisTick: { alignWithLabel: true }
    },
    yAxis: {
      type: 'value',
      axisLabel: {
        formatter: (value: number) => formatValue(value)
      }
    },
    series: props.series.map((s, i) => ({
      name: s.name,
      type: 'line',
      data: s.data,
      smooth: s.smooth ?? true,
      itemStyle: { color: s.color || props.colors[i % props.colors.length] },
      label: props.showValue
        ? {
            show: true,
            position: 'top',
            formatter: (params: any) => formatValue(params.value),
            fontSize: 12
          }
        : { show: false }
    }))
  }
}

function renderChart() {
  if (!chartRef.value) return
  const w = chartRef.value.clientWidth
  const h = chartRef.value.clientHeight
  if (w === 0 || h === 0) {
    setTimeout(renderChart, 100)
    return
  }
  if (!chart) {
    chart = echarts.init(chartRef.value)
  }
  chart.setOption(getOption(), true)
}

onMounted(() => {
  nextTick(() => {
    renderChart()
    window.addEventListener('resize', resizeChart)
  })
})

function resizeChart() {
  chart?.resize()
}

watch(
  () => [props.categories, props.series, props.width, props.height, props.showValue, props.valueFormat, props.precision, props.colors],
  () => {
    renderChart()
    resizeChart()
  },
  { deep: true }
)

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeChart)
  chart?.dispose()
  chart = null
})
</script>

<style scoped>
.line-chart-container {
  width: 100%;
  height: 100%;
  min-width: 100px;
  min-height: 80px;
}
</style> 